#ifndef __losor_type_h__
#define __losor_type_h__

#include <inttype.h>
#include <list.h>
#include "obj_life.h"

typedef struct _token token;
#ifdef __cplusplus
extern "C" {
#endif

    typedef enum _syntype
    {
        T_MACRO,
        T_VAR,
        T_FUNC,
        T_STRUCT,
        T_ENUM,
        T_UNION,
        T_TYPEDEF,

        T_SYSTEM,
        T_PACKAGE,
        T_FILE,
        T_CONST,
        T_LABEL,
    } syntype;

    typedef enum _base_type
    {
        T_SIMPLE,
        T_POINT,
        T_ARRAY,
    } base_type;

    enum vartypeext
    {
        VTE_EXTERN      = 1<<0,
        VTE_STATIC      = 1<<1,
        VTE_CONST       = 1<<2,
        VTE_AUTO        = 1<<3,
        VTE_REGISTER    = 1<<4,
        VTE_RESTRICT    = 1<<5,
        VTE_VOLATILE    = 1<<6,
        VTE_UNSIGNED    = 1<<7,
        VTE_BLONG       = 1<<8,
        VTE_TYPEDEF     = 1<<9,
        VTE_INLINE      = 1<<10,
    };

    typedef struct _vartype
    {
        control_life();
        base_type type;
        void *name;
        //     union{
        //         struct _symbol *st;
        //         struct _pointtype *pt;
        //         struct _arrtype *at;
        //     } name;
        int32 size;
        int32 ext;
    } vartype;

    typedef struct _pointtype
    {
        vartype *base;
    } pointtype;

    typedef struct _arrtype
    {
        vartype *base;
        struct _exp_tree *count;
    } arrtype;

    typedef struct _functype
    {
        vartype* ret;
        list* para;
    } functype;

    typedef struct _structmem
    {
        vartype *type;
        token *name;
    } structmem;

    typedef struct _structtype
    {
        token* name;
        list* member;
    } structtype;

    typedef struct _uniontype
    {
        token *name;
        list *member;
    } uniontype;

    typedef struct _enummember
    {
        token* name;
        int32 val;
    } enummember;

    typedef struct _enumtype
    {
        token *name;
        list *member;
    } enumtype;

    typedef struct _macrotype
    {
        token* name;
        int32 npara;
        list* rep;
        list* para;
    } macrotype;

    typedef struct _symtype
    {
        control_life();
        syntype syn;
        void *attr;
        //     union{
        //         vartype *vt;
        //         functype *ft;
        //         structtype *st;
        //         uniontype *ut;
        //         enumtype *et;
        //         typedeftype *tt;
        //         macrotype *mt;
        //     } attr;
        int size;
    } symtype;

    symtype* symtype_create( syntype ty, void *attr, int size );
    int symtype_release( symtype *ty );
    vartype* vt_create( base_type ty, void *base, int ext );
    int vt_release( vartype *ty );
    char* vt_name( const vartype *vt );
    long vt_size( vartype *ty );
    macrotype* macro_create( token *name, list *para, list *rep );
    int macro_release( macrotype *mt );
    void macro_replace( macrotype *mac, list *para, list *tokens );
    vartype* point_create( vartype *base, int ext );
    vartype* array_create( vartype *base, struct _exp_tree *count, int ext );

#ifdef __cplusplus
};
#endif

#endif // __losor_type_h__
